﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DARE
{
    /// <summary>
    /// This class represents the render globals effects parameters.
    /// </summary>
    public class CEffectMgr
    {
        #region identifier

        public enum EEffectType: uint
        {
            BASIC,
            SKINNED,
            DECALSSKINNED,
            DECALS,
            MULTITEXTURING,
            DECALSMULTITEXTURING
        }

        #endregion

        #region fields

        private Dictionary<EEffectType, CBasicEffect> m_effects = new Dictionary<EEffectType, CBasicEffect>();

        private CRender3D m_render;
        
        private Vector4 ambientLight;
        private Vector3 directionalLight1Direction;
        private Vector4 directionalLight1Diffuse;
        private Vector4 directionalLight1Specular;
        private Vector3 directionalLight2Direction;
        private Vector4 directionalLight2Diffuse;
        private Vector4 directionalLight2Specular;
        private Vector3 directionalLight0Direction;
        private Vector4 directionalLight0Diffuse;
        private Vector4 directionalLight0Specular;
        private bool lighteningEnabled;

        #endregion

        #region properties

        public bool PerPixelLighteningEnabled { get; set; }

        public bool LighteningEnabled
        {
            get { return lighteningEnabled; }
            set { lighteningEnabled = value; }
        }
 
        public Color AmbientLightColor
        {
            get
            {
                return new Color(ambientLight.X / 255.0f, ambientLight.Y / 255.0f, ambientLight.Z / 255.0f);
            }
            set
            {
                ambientLight.X = value.R;
                ambientLight.Y = value.G;
                ambientLight.Z = value.B;
            }
        }

        public float AmbientLightIntensity
        {
            get
            {
                return ambientLight.W;
            }
            set
            {
                ambientLight.W = value;
            }
        }

        public Vector3 DirectionalLight1Direction
        {
            get { return directionalLight1Direction; }
            set { directionalLight1Direction = value; }
        }

        public Color DirectionalLight1DiffuseColor
        {
            get
            {
                return new Color(directionalLight1Diffuse.X / 255.0f, directionalLight1Diffuse.Y / 255.0f, directionalLight1Diffuse.Z / 255.0f);
            }
            set
            {
                directionalLight1Diffuse.X = value.R;
                directionalLight1Diffuse.Y = value.G;
                directionalLight1Diffuse.Z = value.B;
            }
        }

        public float DirectionalLight1DiffuseIntensity
        {
            get { return directionalLight1Diffuse.W; }
            set { directionalLight1Diffuse.W = value; }
        }

        public Color DirectionalLight1SpecularColor
        {
            get { return new Color(directionalLight1Specular.X / 255.0f, directionalLight1Specular.Y / 255.0f, directionalLight1Specular.Z / 255.0f); }
            set
            {
                directionalLight1Specular.X = value.R;
                directionalLight1Specular.Y = value.G;
                directionalLight1Specular.Z = value.B;
            }
        }

        public float DirectionalLight1SpecularIntensity
        {
            get { return directionalLight1Specular.W; }
            set { directionalLight1Specular.W = value; }
        }

        public Vector3 DirectionalLight2Direction
        {
            get { return directionalLight2Direction; }
            set { directionalLight2Direction = value; }
        }

        public Color DirectionalLight2DiffuseColor
        {
            get { return new Color(directionalLight2Diffuse.X / 255.0f, directionalLight2Diffuse.Y / 255.0f, directionalLight2Diffuse.Z / 255.0f); }
            set
            {
                directionalLight2Diffuse.X = value.R;
                directionalLight2Diffuse.Y = value.G;
                directionalLight2Diffuse.Z = value.B;
            }
        }

        public float DirectionalLight2DiffuseIntensity
        {
            get { return directionalLight2Diffuse.W; }
            set { directionalLight2Diffuse.W = value; }
        }

        public Color DirectionalLight2SpecularColor
        {
            get { return new Color(directionalLight2Specular.X / 255.0f, directionalLight2Specular.Y / 255.0f, directionalLight2Specular.Z / 255.0f); }
            set
            {
                directionalLight2Specular.X = value.R;
                directionalLight2Specular.Y = value.G;
                directionalLight2Specular.Z = value.B;
            }
        }

        public float DirectionalLight2SpecularIntensity
        {
            get { return directionalLight2Specular.W; }
            set { directionalLight2Specular.W = value; }
        }

        public Vector3 DirectionalLight0Direction
        {
            get { return directionalLight0Direction; }
            set { directionalLight0Direction = value; }
        }

        public Color DirectionalLight0DiffuseColor
        {
            get { return new Color(directionalLight0Diffuse.X / 255.0f, directionalLight0Diffuse.Y / 255.0f, directionalLight0Diffuse.Z / 255.0f); }
            set
            {
                directionalLight0Diffuse.X = value.R;
                directionalLight0Diffuse.Y = value.G;
                directionalLight0Diffuse.Z = value.B;
            }
        }

        public float DirectionalLight0DiffuseIntensity
        {
            get { return directionalLight0Diffuse.W; }
            set { directionalLight0Diffuse.W = value; }
        }

        public Color DirectionalLight0SpecularColor
        {
            get { return new Color(directionalLight0Specular.X / 255.0f, directionalLight0Specular.Y / 255.0f, directionalLight0Specular.Z / 255.0f); }
            set
            {
                directionalLight0Specular.X = value.R;
                directionalLight0Specular.Y = value.G;
                directionalLight0Specular.Z = value.B;
            }
        }

        public float DirectionalLight0SpecularIntensity
        {
            get { return directionalLight0Specular.W; }
            set { directionalLight0Specular.W = value; }
        }

        #endregion

        #region ctor

        public CEffectMgr(CRender3D render3D)
        {
            m_render = render3D;
            directionalLight1Diffuse = new Vector4(1, 1, 1, 0);
            directionalLight1Specular = new Vector4(1, 1, 1, 0);
            directionalLight2Diffuse = new Vector4(1, 1, 1, 0);
            directionalLight2Specular = new Vector4(1, 1, 1, 0);
            directionalLight0Diffuse = new Vector4(1, 1, 1, 0);
            directionalLight0Specular = new Vector4(1, 1, 1, 0);
            ambientLight = new Vector4(1, 1, 1, 0);

            m_effects.Add(EEffectType.BASIC, new CBasicEffect());
            m_effects.Add(EEffectType.SKINNED, new CSkinnedBasicEffect());
            m_effects.Add(EEffectType.DECALS, new CDecalsBasicEffect());
            m_effects.Add(EEffectType.DECALSSKINNED, new CDecalsSkinnedBasicEffect());
            m_effects.Add(EEffectType.MULTITEXTURING, new CMultiTexturingBasicEffect());
            m_effects.Add(EEffectType.DECALSMULTITEXTURING, new CDecalsMultiTexturingBasicEffect());



        }

        #endregion

        #region methods

        public CBasicEffect GetEffect(EEffectType type)
        {
            return m_effects[type];
        }

        #endregion
    }
}
